/**
 * 微信支付工具类
 * 对接 server-aes-wxpay 后端的微信支付接口
 * 
 * 🔐 加密说明：
 * - 小程序登录接口：不需要加密
 * - 创建订单接口：需要AES加密
 * - 查询订单接口：不需要加密
 */

const aes = require('./aes.js');
const storage = require('./storage.js');

class WxPayUtil {
  constructor() {
    // 后端服务器地址（强制使用生产环境）
    this.baseUrl = 'https://api.playtruly.cn';
    
    // 立即验证配置
    console.log('🔧 WxPayUtil 初始化');
    console.log('📍 当前 baseUrl:', this.baseUrl);
    console.log('⏰ 初始化时间:', new Date().toISOString());
  }

  /**
   * 获取用户 openid
   * @returns {Promise<string>} openid
   */
  async getOpenId() {
    try {
      // 先尝试从缓存获取
      const cachedOpenId = wx.getStorageSync('wx_openid');
      if (cachedOpenId) {
        console.log('✅ 使用缓存的 openid:', cachedOpenId);
        return cachedOpenId;
      }

      // 调用 wx.login 获取 code
      console.log('🔐 开始微信登录获取 code...');
      const loginRes = await this._wxLogin();
      const code = loginRes.code;
      
      if (!code) {
        throw new Error('获取微信登录 code 失败');
      }

      console.log('✅ 获取 code 成功:', code);

      // 调用后端接口获取 openid
      const loginUrl = `${this.baseUrl}/api/wx/miniapp/login`;
      console.log('🔄 调用后端接口获取 openid...');
      console.log('📍 请求地址:', loginUrl);
      console.log('🔑 当前 baseUrl:', this.baseUrl);
      
      const response = await this._request({
        url: loginUrl,
        method: 'POST',
        data: { code }
      });

      if (response.code === 200 && response.data && response.data.openid) {
        const openid = response.data.openid;
        console.log('✅ 获取 openid 成功:', openid);
        
        // 缓存 openid
        wx.setStorageSync('wx_openid', openid);
        return openid;
      } else {
        throw new Error(response.msg || '获取 openid 失败');
      }
    } catch (error) {
      console.error('❌ 获取 openid 失败:', error);
      throw error;
    }
  }

  /**
   * 创建支付订单（需要AES加密）
   * @param {Object} params - 订单参数
   * @param {number} params.user_id - 用户ID
   * @param {number} params.package_id - 套餐ID
   * @param {string} params.openid - 用户openid
   * @returns {Promise<Object>} 支付参数
   */
  async createOrder(params) {
    try {
      console.log('💰 ========== 创建微信支付订单 ==========');
      console.log('📦 订单参数:', params);

      // 🔐 构建请求数据（需要加密）
      const requestData = {
        user_id: params.user_id,
        package_id: params.package_id,
        openid: params.openid,
        timestamp: Math.floor(Date.now() / 1000)  // 秒级时间戳
      };

      console.log('📊 请求参数（加密前）:', requestData);

      // 🔐 使用AES加密
      const encryptedPayload = aes.createEncryptedPayload(requestData);
      console.log('🔐 加密载荷已生成');

      // 发送加密请求
      const response = await this._request({
        url: `${this.baseUrl}/api/payment/wxpay/create_order`,
        method: 'POST',
        data: encryptedPayload
      });

      console.log('📨 订单响应:', response);

      if (response.status === 'success' && response.pay_params) {
        console.log('✅ 订单创建成功');
        console.log('📝 订单号:', response.out_trade_no);
        console.log('💳 支付参数:', response.pay_params);
        return {
          out_trade_no: response.out_trade_no,
          pay_params: response.pay_params
        };
      } else {
        throw new Error(response.error || response.message || '创建订单失败');
      }
    } catch (error) {
      console.error('❌ 创建订单失败:', error);
      throw error;
    }
  }

  /**
   * 发起微信支付
   * @param {Object} payParams - 支付参数
   * @returns {Promise<Object>} 支付结果
   */
  async requestPayment(payParams) {
    try {
      console.log('💰 发起微信支付:', payParams);

      return new Promise((resolve, reject) => {
        wx.requestPayment({
          timeStamp: payParams.timeStamp,
          nonceStr: payParams.nonceStr,
          package: payParams.package,
          signType: payParams.signType,
          paySign: payParams.paySign,
          success: (res) => {
            console.log('✅ 支付成功:', res);
            resolve(res);
          },
          fail: (err) => {
            console.error('❌ 支付失败:', err);
            if (err.errMsg.includes('cancel')) {
              reject(new Error('用户取消支付'));
            } else {
              reject(new Error('支付失败: ' + err.errMsg));
            }
          }
        });
      });
    } catch (error) {
      console.error('❌ 调起支付失败:', error);
      throw error;
    }
  }

  /**
   * 查询订单状态
   * @param {string} outTradeNo - 商户订单号
   * @returns {Promise<Object>} 订单信息
   */
  async queryOrder(outTradeNo) {
    try {
      console.log('🔍 查询订单状态:', outTradeNo);

      const response = await this._request({
        url: `${this.baseUrl}/api/payment/wxpay/query/${outTradeNo}`,
        method: 'GET'
      });

      // ✅ 后端现在返回的是 status_code=200，需要检查 code 字段
      if (response.code === 200 && response.data) {
        console.log('✅ 查询订单成功:', response.data);
        return response.data;
      } else if (response.code === 500) {
        // 查询失败，但不影响支付结果
        console.warn('⚠️ 查询订单失败，但不影响支付:', response.msg);
        throw new Error(response.msg || '查询订单失败');
      } else {
        throw new Error(response.msg || '查询订单失败');
      }
    } catch (error) {
      console.error('❌ 查询订单失败:', error);
      throw error;
    }
  }

  /**
   * 完整的支付流程
   * @param {Object} params - 支付参数
   * @param {number} params.user_id - 用户ID
   * @param {number} params.package_id - 套餐ID
   * @param {string} params.package_name - 套餐名称
   * @param {number} params.price - 套餐价格
   * @param {number} params.points - 积分数量
   * @returns {Promise<Object>} 支付结果
   */
  async doPay(params) {
    try {
      console.log('🚀 ========== 开始微信支付流程 ==========');
      console.log('📝 支付参数:', params);

      // 1. 获取 openid
      wx.showLoading({ title: '正在登录...', mask: true });
      const openid = await this.getOpenId();
      wx.hideLoading();

      // 2. 创建订单
      wx.showLoading({ title: '正在创建订单...', mask: true });
      const orderResult = await this.createOrder({
        user_id: params.user_id,
        package_id: params.package_id,
        openid: openid
      });
      wx.hideLoading();

      const { out_trade_no, pay_params } = orderResult;

      // 3. 确认支付
      const confirmRes = await this._showConfirmDialog({
        title: '确认支付',
        content: `套餐：${params.package_name}\n积分：${params.points}\n金额：¥${params.price}\n\n确认使用微信支付购买？`
      });

      if (!confirmRes.confirm) {
        throw new Error('用户取消支付');
      }

      // 4. 调起微信支付
      wx.showLoading({ title: '正在调起支付...', mask: true });
      await this.requestPayment(pay_params);
      wx.hideLoading();

      // 5. 支付成功，等待2秒后查询订单状态
      wx.showLoading({ title: '支付成功，正在确认...', mask: true });
      await this._sleep(2000);
      
      // 🔄 尝试查询订单状态（如果失败也不影响支付结果）
      let orderInfo = null;
      try {
        orderInfo = await this.queryOrder(out_trade_no);
        console.log('✅ 订单查询成功:', orderInfo);
      } catch (queryError) {
        console.warn('⚠️ 订单查询失败，但不影响支付结果:', queryError);
        // 查询失败不影响支付成功的判断，因为积分会通过异步回调发放
      }
      
      wx.hideLoading();

      console.log('✅ ========== 微信支付流程完成 ==========');
      console.log('📊 订单信息:', orderInfo);

      return {
        success: true,
        out_trade_no,
        orderInfo,
        message: '支付成功，积分将在几分钟内到账'
      };

    } catch (error) {
      wx.hideLoading();
      console.error('❌ ========== 微信支付流程失败 ==========');
      console.error('错误信息:', error);
      
      return {
        success: false,
        error: error.message || '支付失败',
        message: error.message || '支付失败'
      };
    }
  }

  /**
   * 封装 wx.login
   * @private
   */
  _wxLogin() {
    return new Promise((resolve, reject) => {
      wx.login({
        success: resolve,
        fail: reject
      });
    });
  }

  /**
   * 封装 wx.request
   * @private
   */
  _request(options) {
    return new Promise((resolve, reject) => {
      wx.request({
        ...options,
        success: (res) => {
          if (res.statusCode === 200) {
            resolve(res.data);
          } else {
            reject(new Error(`请求失败: ${res.statusCode}`));
          }
        },
        fail: reject
      });
    });
  }

  /**
   * 显示确认对话框
   * @private
   */
  _showConfirmDialog(options) {
    return new Promise((resolve) => {
      wx.showModal({
        ...options,
        success: resolve,
        fail: () => resolve({ confirm: false })
      });
    });
  }

  /**
   * 延迟函数
   * @private
   */
  _sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// 导出单例
module.exports = new WxPayUtil();
